home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / gfx / misc / gnuplot-src.lha / gnuplot-3.7.1src / gnuplot-3.7.1.lha / gnuplot-3.7.1 / term / gif.trm < prev    next >
Encoding:
Text File  |  1999-09-29  |  17.1 KB  |  577 lines

  1. /*
  2.  * $Id: gif.trm,v 1.12.2.3 1999/09/29 13:53:53 lhecking Exp $
  3.  */
  4.  
  5. /* GNUPLOT -- gif.trm */
  6.  
  7. /*[
  8.  * Copyright 1998
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted,
  12.  * provided that the above copyright notice appear in all copies and
  13.  * that both that copyright notice and this permission notice appear
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the complete modified source code.  Modifications are to
  18.  * be distributed as patches to the released version.  Permission to
  19.  * distribute binaries produced by compiling modified sources is granted,
  20.  * provided you
  21.  *   1. distribute the corresponding source modifications from the
  22.  *    released version in the form of a patch file along with the binaries,
  23.  *   2. add special version identification to distinguish your version
  24.  *    in addition to the base release version number,
  25.  *   3. provide your name and address as the primary contact for the
  26.  *    support of your modified version, and
  27.  *   4. retain our contact information in regard to use of the base
  28.  *    software.
  29.  * Permission to distribute the released version of the source code along
  30.  * with corresponding source modifications in the form of a patch file is
  31.  * granted with same provisions 2 through 4 for binary distributions.
  32.  *
  33.  * This software is provided "as is" without express or implied warranty
  34.  * to the extent permitted by applicable law.
  35. ]*/
  36.  
  37. /*
  38.  * This file is included by ../term.c.
  39.  *
  40.  * This terminal driver supports:
  41.  *  GD GIF library 1.2 & 1.3
  42.  *
  43.  * To Use:
  44.  *
  45.  * set terminal gif ?options ...?
  46.  *
  47.  * Where an option is:
  48.  *
  49.  * transparent - generate transparent GIFs.  The first color will
  50.  * be the transparent one.
  51.  *
  52.  * interlace - generate interlaced GIFs.
  53.  *
  54.  * size (in pixels)
  55.  *
  56.  * font (tiny,small,medium,large,giant)
  57.  *
  58.  * xrrggbb - sets the next color.  x is the literal character 'x',
  59.  * rrggbb are the red green and blue components in hex.  For example
  60.  * x00ff00 is green.  The background color is set first, then the
  61.  * color borders, then the X & Y axis, then the plotting colors.
  62.  * (The wierd color spec is in order to get around limitations
  63.  * in gnuplot's scanner.)
  64.  *
  65.  * This driver is modeled after the PBM driver pbm.trm.
  66.  *
  67.  * AUTHORS
  68.  *  Sam Shen <sls@mh1.lbl.gov>
  69.  *  Alex Woo <woo@playfair.stanford.edu>
  70.  *
  71.  * CONTRIBUTORS
  72.  *  Alfred Reibenschuh <alfred.reibenschuh@it-austria.com> or <fredo@blackbox.at>
  73.  *  Ben Laurie <ben@algroup.co.uk>
  74.  *
  75.  * send your comments or suggestions to:
  76.  *  info-gnuplot@cs.dartmouth.edu
  77.  * 
  78.  * This version outputs either color or monochrome GIFs.  The default
  79.  * is 640x480 pixels.  
  80.  *
  81.  * link with -Lterm/gd -lgd if your directory structure is gnuplot/term/gd
  82.  *
  83.  * gd is not distributed with gnuplot, because of the UNISYS license thing.
  84.  *
  85.  * find out about gd from http://www.boutell.com/gd/
  86.  *
  87.  * Gd library versions before 1.3, and gd library 1.5 are subject to
  88.  * the Unisys license. Use at your own risk. From version 1.6 on, gd
  89.  * library creates png files instead of gif.
  90.  *
  91.  */
  92.  
  93. #include "driver.h"
  94.  
  95. #ifdef TERM_REGISTER
  96. register_term(gif)
  97. #endif
  98.  
  99. #ifdef TERM_PROTO
  100. TERM_PUBLIC void GIF_options __PROTO((void));
  101. TERM_PUBLIC void GIF_init __PROTO((void));
  102. TERM_PUBLIC void GIF_graphics __PROTO((void));
  103. TERM_PUBLIC void GIF_text __PROTO((void));
  104. TERM_PUBLIC void GIF_linetype __PROTO((int linetype));
  105. TERM_PUBLIC void GIF_move __PROTO((unsigned int x, unsigned int y));
  106. TERM_PUBLIC void GIF_vector __PROTO((unsigned int x, unsigned int y));
  107. TERM_PUBLIC void GIF_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
  108. TERM_PUBLIC int GIF_text_angle __PROTO((int ang));
  109. TERM_PUBLIC void GIF_reset __PROTO((void));
  110.  
  111. #include "gd.h"
  112.  
  113. extern gdFontPtr gdFontSmall;    /* 6x12 */
  114. extern gdFontPtr gdFontLarge;    /* 8x16 */
  115. extern gdFontPtr gdFontMediumBold;    /* 7x13 */
  116. extern gdFontPtr gdFontGiant;  /* 9x15 */
  117. extern gdFontPtr gdFontTiny;  /* 5x8 */
  118.  
  119.  
  120. #define GREG_XMAX 640
  121. #define GREG_YMAX 480
  122.  
  123.  
  124. static int GIF_XMAX = GREG_XMAX;
  125. static int GIF_YMAX = GREG_YMAX;
  126.  
  127.  
  128. #define GIF_FONT_SMALL 1
  129. #ifdef GIF_FONT_SMALL
  130. # define gdfont gdFontSmall
  131. # define GIF_VCHAR 12
  132. # define GIF_HCHAR 6
  133. #else
  134. # define gdfont gdFontMediumBold
  135. # define GIF_VCHAR 13
  136. # define GIF_HCHAR 7
  137. #endif
  138.  
  139. static gdFontPtr GIF_font;
  140.  
  141. #define GIF_VTIC (GREG_YMAX/100)
  142. #define GIF_HTIC (GREG_XMAX/150)
  143.  
  144. #define GIF_MAX_COLORS 256
  145. #define GOT_NEXT_PROTO
  146. #endif
  147.  
  148. #ifndef TERM_PROTO_ONLY
  149. #ifdef TERM_BODY
  150.  
  151. static struct {
  152.     gdImagePtr image;
  153.     gdFontPtr font;
  154.     unsigned int x, y;
  155.     int height;
  156.     int charh, charw;
  157.     int color;
  158.     int n_colors;
  159.     int color_table[GIF_MAX_COLORS];
  160.     int rgb_table[GIF_MAX_COLORS];
  161.     int angle;
  162.     int flags;
  163.     int linetype;
  164. } gif_state;
  165.  
  166. #define GIF_USE_TRANSPARENT 1
  167. #define GIF_USE_INTERLACE   2
  168.  
  169. /*
  170.  * _options()  Called when terminal type is selected.  
  171.  * This procedure should parse options on the command line.  A list of the 
  172.  * currently selected options should be stored in term_options[] in a form 
  173.  * suitable for use with the set term command.  term_options[] is used by 
  174.  * the save command.  Use options_null() if no options are available. 
  175.  */
  176. TERM_PUBLIC void
  177. GIF_options()
  178. {
  179.     struct value s;
  180.     int gif_font, i;
  181.     char *string;
  182.     unsigned long color;
  183.     
  184.     term_options[0] = NUL;
  185.     gif_state.n_colors = 0;
  186.     gif_state.flags = 0;
  187.     gif_font = 1;
  188.     GIF_font = gdfont;
  189.  
  190.     while (!END_OF_COMMAND) {
  191.     if (almost_equals(c_token, "t$ransparent")) {
  192.         gif_state.flags |= GIF_USE_TRANSPARENT;
  193.         ++c_token;
  194.     } else if (almost_equals(c_token, "i$nterlace")) {
  195.         gif_state.flags |= GIF_USE_INTERLACE;
  196.         ++c_token;
  197.     } else if (almost_equals(c_token, "ti$ny")) {
  198.         GIF_font=gdFontTiny;
  199.         gif_font = 0;
  200.         term->v_char = (unsigned int)(8);
  201.         term->h_char = (unsigned int)(5);
  202.         ++c_token;
  203.     } else if (almost_equals(c_token, "s$mall")) {
  204.         GIF_font = gdFontSmall;
  205.         gif_font = 1;
  206.         term->v_char = (unsigned int) (12);
  207.         term->h_char = (unsigned int) (6);
  208.         ++c_token;
  209.     } else if (almost_equals(c_token, "m$edium")) {
  210.         GIF_font = gdFontMediumBold;
  211.         gif_font = 2;
  212.         term->v_char = (unsigned int) (13);
  213.         term->h_char = (unsigned int) (7);
  214.         ++c_token;
  215.     } else if (almost_equals(c_token, "l$arge")) {
  216.         GIF_font = gdFontLarge;
  217.         gif_font = 3;
  218.         term->v_char = (unsigned int) (16);
  219.         term->h_char = (unsigned int) (8);
  220.         ++c_token;
  221.     } else if (almost_equals(c_token, "l$arge")) {
  222.         GIF_font=gdFontGiant;
  223.         gif_font = 4;
  224.         term->v_char = (unsigned int)(15);
  225.         term->h_char = (unsigned int)(9);
  226.         ++c_token;
  227.     } else if (almost_equals(c_token, "si$ze")) {
  228.         c_token++;
  229.         if (END_OF_COMMAND) {
  230.         GIF_XMAX = GREG_XMAX;
  231.         GIF_YMAX = GREG_YMAX;
  232.         term->v_tic = GIF_YMAX / 80;
  233.         term->h_tic = GIF_XMAX / 80;
  234.         } else {
  235.         GIF_XMAX = real(const_express(&s));
  236.         if (equals(c_token, ",")) {
  237.             c_token++;
  238.             GIF_YMAX = real(const_express(&s));
  239.             term->v_tic = GIF_YMAX / 80;
  240.             term->h_tic = GIF_XMAX / 80;
  241.             term->ymax = GIF_YMAX;
  242.             term->xmax = GIF_XMAX;
  243.         }
  244.         }
  245.     } else {                /* not "size" */
  246.         string = input_line + token[c_token].start_index;
  247.         if (sscanf(string, "x%lx", &color) != 1) {
  248.         int_error("invalid color spec, must be xRRGGBB",c_token);
  249.         } else if (gif_state.n_colors == GIF_MAX_COLORS) {
  250.         int_warn("too many colors, ingoring",c_token);
  251.         ++c_token;
  252.         } else {
  253.         gif_state.rgb_table[gif_state.n_colors++] = color;
  254.         ++c_token;
  255.         }
  256.     }
  257.     }
  258.  
  259.  
  260.     /* now generate options string */
  261.  
  262.     if (gif_state.flags & GIF_USE_TRANSPARENT) {
  263.     strcat(term_options, "transparent ");
  264.     }
  265.     if (gif_state.flags & GIF_USE_INTERLACE) {
  266.     strcat(term_options, "interlace ");
  267.     }
  268.     switch (gif_font) {
  269.     case 0:
  270.     strcat(term_options,"tiny ");
  271.     break;
  272.     case 1:
  273.     strcat(term_options, "small ");
  274.     break;
  275.     case 2:
  276.     strcat(term_options, "medium ");
  277.     break;
  278.     case 3:
  279.     strcat(term_options, "large ");
  280.     break;
  281.     case 4:
  282.     strcat(term_options,"giant ");
  283.     break;
  284.     }
  285.     sprintf(term_options + strlen(term_options),
  286.         "size %d,%d ", GIF_XMAX, GIF_YMAX);
  287.  
  288.     for (i = 0; i < gif_state.n_colors; i++) {
  289.     sprintf(term_options + strlen(term_options),
  290.         "x%06x ", gif_state.rgb_table[i]);
  291.     }
  292. }
  293.  
  294.  
  295. /*
  296.  * _init()  Called once, when the device is first selected.  This procedure
  297.  * should set up things that only need to be set once, like handshaking and
  298.  * character sets etc...
  299.  */
  300. TERM_PUBLIC void
  301. GIF_init()
  302. {
  303.     gif_state.linetype = 0;
  304. }
  305.  
  306. /*
  307.  * _reset()  Called when gnuplot is exited, the output device changed or
  308.  * the terminal type changed.  This procedure should reset the device, 
  309.  * possibly flushing a buffer somewhere or generating a form feed.
  310.  */
  311. TERM_PUBLIC void
  312. GIF_reset()
  313. {
  314. }
  315.  
  316. /*
  317.  * _graphics()  Called just before a plot is going to be displayed.  This
  318.  * procedure should set the device into graphics mode.  Devices which can't
  319.  * be used as terminals (like plotters) will probably be in graphics mode 
  320.  * always and therefore won't need this.
  321.  */
  322. TERM_PUBLIC void
  323. GIF_graphics()
  324. {
  325.     int i;
  326.     unsigned int rgb;
  327.     gif_state.font = GIF_font;
  328.     gif_state.color = 0;
  329.     gif_state.image = gdImageCreate((int) (xsize * GIF_XMAX),
  330.                     (int) (ysize * GIF_YMAX));
  331.     gif_state.height = (int) (ysize * GIF_YMAX - 1);
  332.     gif_state.charw = term->h_char;    /* gif_state.font->w; */
  333.     gif_state.charh = term->v_char;    /* gif_state.font->h; */
  334.     for (i = gif_state.n_colors; i < WEB_N_COLORS; i++)
  335.     gif_state.rgb_table[i] = 
  336.         (web_color_rgbs[i].r << 16) |
  337.         (web_color_rgbs[i].g << 8) |
  338.         web_color_rgbs[i].b;
  339.     if (gif_state.n_colors < WEB_N_COLORS)
  340.     gif_state.n_colors = WEB_N_COLORS;
  341.     for (i = 0; i < gif_state.n_colors; i++) {
  342.     rgb = gif_state.rgb_table[i];
  343.     gif_state.color_table[i] =
  344.         gdImageColorAllocate(gif_state.image, (rgb >> 16) & 0xff,
  345.                  (rgb >> 8) & 0xff, rgb & 0xff);
  346.     }
  347.     if (gif_state.flags & GIF_USE_TRANSPARENT)
  348.     gdImageColorTransparent(gif_state.image,
  349.                 gif_state.color_table[0]);
  350.     else
  351.     gdImageColorTransparent(gif_state.image, -1);
  352. }
  353.  
  354. /* 
  355.  * _text()  Called immediately after a plot is displayed.  This procedure 
  356.  * should set the device back into text mode if it is also a terminal, so
  357.  * that commands can be seen as they're typed.  Again, this will probably
  358.  * do nothing if the device can't be used as a terminal.
  359.  */
  360. TERM_PUBLIC void
  361. GIF_text()
  362. {
  363.     if (gif_state.flags & GIF_USE_INTERLACE)
  364.     gdImageInterlace(gif_state.image, 1);
  365.     gdImageGif(gif_state.image, gpoutfile);
  366.     gdImageDestroy(gif_state.image);
  367. }
  368.  
  369. /* _move(x,y)  Called at the start of a line.  The cursor should move to the
  370.  * (x,y) position without drawing.
  371.  */
  372. TERM_PUBLIC void
  373. GIF_move(unsigned int x, unsigned int y)
  374. {
  375.     gif_state.x = x;
  376.     gif_state.y = y;
  377. }
  378.  
  379. /* _vector(x,y)  Called when a line is to be drawn.  This should display a line
  380.  * from the last (x,y) position given by _move() or _vector() to this new (x,y)
  381.  * position.
  382.  */
  383. TERM_PUBLIC void
  384. GIF_vector(unsigned int x, unsigned int y)
  385. {
  386.     int gif_linetype_dotted[5];
  387.  
  388.     if (gif_state.linetype == -1) {
  389.     gif_linetype_dotted[0] = gif_state.color_table[2];
  390.     gif_linetype_dotted[1] = gif_state.color_table[2];
  391.     gif_linetype_dotted[2] = gif_state.color_table[0];
  392.     gif_linetype_dotted[3] = gif_state.color_table[0];
  393.     gif_linetype_dotted[4] = gif_state.color_table[0];
  394.  
  395.     gdImageSetStyle(gif_state.image, gif_linetype_dotted, 5);
  396.     gdImageLine(gif_state.image, gif_state.x, gif_state.height - gif_state.y,
  397.             x, gif_state.height - y, gdStyled);
  398.     } else {
  399.     gdImageLine(gif_state.image, gif_state.x, gif_state.height - gif_state.y,
  400.             x, gif_state.height - y, gif_state.color);
  401.     }
  402.     gif_state.x = x;
  403.     gif_state.y = y;
  404. }
  405.  
  406. /* _linetype(lt)  Called to set the line type before text is displayed or
  407.  * line(s) plotted.  This procedure should select a pen color or line
  408.  * style if the device has these capabilities.  
  409.  * lt is an integer from -2 to 0 or greater.  
  410.  * An lt of -2 is used for the border of the plot.
  411.  * An lt of -1 is used for the X and Y axes.  
  412.  * lt 0 and upwards are used for plots 0 and upwards.
  413.  * If _linetype() is called with lt greater than the available line types, 
  414.  * it should map it to one of the available line types.
  415.  * Most drivers provide 9 different linetypes (lt is 0 to 8).
  416.  */
  417. TERM_PUBLIC void
  418. GIF_linetype(int type)
  419. {
  420.     if (type >= (gif_state.n_colors - 3))
  421.     type %= (gif_state.n_colors - 3);
  422.  
  423.     gif_state.color = gif_state.color_table[type + 3];
  424.     gif_state.linetype = type;
  425. }
  426.  
  427. /* _put_text(x,y,str)  Called to display text at the (x,y) position, 
  428.  * while in graphics mode.   The text should be vertically (with respect 
  429.  * to the text) justified about (x,y).  The text is rotated according 
  430.  * to _text_angle and then horizontally (with respect to the text)
  431.  * justified according to _justify_text.
  432.  */
  433. TERM_PUBLIC void
  434. GIF_put_text(unsigned int x, unsigned int y, char *string)
  435. {
  436.     if (gif_state.angle == 1) {
  437.     x -= gif_state.charh / 2;
  438.     gdImageStringUp(gif_state.image, gif_state.font,
  439.             x, gif_state.height - y,
  440.             string, gif_state.color);
  441.     } else {
  442.     y += gif_state.charh / 2;
  443.     gdImageString(gif_state.image, gif_state.font,
  444.               x, gif_state.height - y,
  445.               string, gif_state.color);
  446.     }
  447. }
  448.  
  449. /* _text_angle(ang)  Called to rotate the text angle when placing the y label.
  450.  * If ang = 0 then text is horizontal.  If ang = 1 then text is vertically
  451.  * upwards.  Returns TRUE if text can be rotated, FALSE otherwise.
  452.  */
  453. TERM_PUBLIC int
  454. GIF_text_angle(int ang)
  455. {
  456.     gif_state.angle = ang;
  457.     return TRUE;
  458. }
  459.  
  460. TERM_PUBLIC int
  461. GIF_set_font(char *fontname)
  462. {
  463.     char name[32];
  464.     int  sep;
  465.     gdFontPtr font;
  466.  
  467.     sep = strcspn(fontname,",");
  468.     strncpy(name,fontname,sep);
  469.     name[sep] = NUL;
  470.  
  471.     if (!strcmp(fontname,"small"))
  472.     font = gdFontSmall;
  473.     else if (!strcmp(fontname,"medium"))
  474.     font = gdFontMediumBold;
  475.     else if(!strcmp(fontname,"large"))
  476.     font = gdFontLarge;
  477.     else if(!strcmp(fontname,"giant"))
  478.     font = gdFontGiant;
  479.     else if(!strcmp(fontname,"tiny"))
  480.     font = gdFontTiny;
  481.     else
  482.     font = GIF_font;
  483.  
  484.     gif_state.charw = font->w;
  485.     gif_state.charh = font->h;
  486.  
  487.     gif_state.font = font;
  488.  
  489.     return TRUE;
  490. }
  491.  
  492. #endif /* TERM_BODY */
  493. #ifdef TERM_TABLE
  494.  
  495. TERM_TABLE_START(gif_driver)
  496.     "gif", "GIF format [mode] [fontsize] [size] [colors]",
  497.     GREG_XMAX, GREG_YMAX, GIF_VCHAR, GIF_HCHAR,
  498.     GIF_VTIC, GIF_HTIC, GIF_options, GIF_init, GIF_reset,
  499.     GIF_text, null_scale, GIF_graphics, GIF_move, GIF_vector,
  500.     GIF_linetype, GIF_put_text, GIF_text_angle,
  501.     null_justify_text, do_point, do_arrow, GIF_set_font,
  502.     0,                /* pointsize */
  503.     TERM_CAN_MULTIPLOT | TERM_BINARY
  504. TERM_TABLE_END(gif_driver)
  505.  
  506. #undef LAST_TERM
  507. #define LAST_TERM gif_driver
  508.  
  509. #endif /* TERM_TABLE */
  510. #endif /* TERM_PROTO_ONLY */
  511.  
  512. #ifdef TERM_HELP
  513. START_HELP(gif)
  514. "1 gif",
  515. "?commands set terminal gif",
  516. "?set terminal gif",
  517. "?set term gif",
  518. "?terminal gif",
  519. "?term gif",
  520. "?gif",
  521. " The `gif` terminal driver generates output in GIF format.  It uses Thomas",
  522. " Boutell's gd library, which is available from http://www.boutell.com/gd/",
  523. "",
  524. " By default, the `gif` terminal driver uses a shared Web-friendy palette."
  525. "",
  526. " Syntax:",
  527. "       set terminal gif {transparent} {interlace}",
  528. "                        {tiny | small | medium | large | giant}",
  529. "                        {size <x>,<y>}",
  530. "                        {<color0> <color1> <color2> ...}",
  531. "",
  532. " `transparent` instructs the driver to generate transparent GIFs.  The first",
  533. " color will be the transparent one.",
  534. "",
  535. " `interlace` instructs the driver to generate interlaced GIFs.",
  536. "",
  537. " The choice of fonts is `tiny` (5x8 pixels), `small` (6x12 pixels), `medium`",
  538. " (7x13 Bold), `large` (8x16) or `giant` (9x15 pixels)",
  539. "",
  540. " The size <x,y> is given in pixels---it defaults to 640x480.  The number of",
  541. " pixels can be also modified by scaling with the `set size` command.",
  542. "",
  543. " Each color must be of the form 'xrrggbb', where x is the literal character",
  544. " 'x' and 'rrggbb' are the red, green and blue components in hex.  For example,",
  545. " 'x00ff00' is green.  The background color is set first, then the border",
  546. " colors, then the X & Y axis colors, then the plotting colors.  The maximum",
  547. " number of colors that can be set is 256.",
  548. "",
  549. " Examples:",
  550. "       set terminal gif small size 640,480 \\",
  551. "                        xffffff x000000 x404040 \\",
  552. "                        xff0000 xffa500 x66cdaa xcdb5cd \\",
  553. "                        xadd8e6 x0000ff xdda0dd x9500d3    # defaults",
  554. "",
  555. " which uses white for the non-transparent background, black for borders, gray",
  556. " for the axes, and red, orange, medium aquamarine, thistle 3, light blue, blue,",
  557. " plum and dark violet for eight plotting colors.",
  558. "",
  559. "       set terminal gif transparent xffffff \\",
  560. "                        x000000 x202020 x404040 x606060 \\",
  561. "                        x808080 xA0A0A0 xC0C0C0 xE0E0E0 \\",
  562. " which uses white for the transparent background, black for borders, dark",
  563. " gray for axes, and a gray-scale for the six plotting colors.",
  564. "",
  565. " The page size is 640x480 pixels.  The `gif` driver can create either color",
  566. " or monochromatic output, but you have no control over which is produced.",
  567. "",
  568. " The current version of the `gif` driver does not support animated GIFs."
  569. END_HELP(gif)
  570. #endif /* TERM_HELP */
  571.  
  572. /*
  573.  * Local Variables:
  574.  * mode:C
  575.  * End:
  576.  */
  577.